import * as vscode from 'vscode';
import axios from 'axios';
import { Commit } from './gitService';

export interface AIConfig {
    baseUrl: string;
    apiKey: string;
    model: string;
    systemPrompt?: string;
}

export class AIService {
    private config: AIConfig | null = null;
    private defaultSystemPrompt = "You are a helpful assistant that summarizes git commits into meaningful product change points. Please automatically adjust the language of your responses based on the primary language of the git commits. If most of the commits are in Chinese, please respond in Chinese; if most of the commits are in English, please respond in English.";

    constructor() {
        this.loadConfig();
    }

    private loadConfig(): void {
        const config = vscode.workspace.getConfiguration('gitsummary.ai');
        const baseUrl = config.get<string>('baseUrl');
        const apiKey = config.get<string>('apiKey');
        const model = config.get<string>('model');
        const systemPrompt = config.get<string>('systemPrompt') || this.defaultSystemPrompt;

        if (baseUrl && apiKey && model) {
            this.config = {
                baseUrl,
                apiKey,
                model,
                systemPrompt
            };
        } else {
            this.config = null;
        }
    }

    public async saveConfig(config: AIConfig): Promise<void> {
        const configuration = vscode.workspace.getConfiguration('gitsummary.ai');
        await configuration.update('baseUrl', config.baseUrl, vscode.ConfigurationTarget.Global);
        await configuration.update('apiKey', config.apiKey, vscode.ConfigurationTarget.Global);
        await configuration.update('model', config.model, vscode.ConfigurationTarget.Global);
        await configuration.update('systemPrompt', config.systemPrompt, vscode.ConfigurationTarget.Global);
        this.config = config;
    }

    public getConfig(): AIConfig | null {
        return this.config;
    }

    public isConfigured(): boolean {
        return this.config !== null;
    }

    public async generateSummaryWithAI(commits: Commit[]): Promise<string | null> {
        if (!this.isConfigured()) {
            throw new Error('AI is not configured. Please configure AI settings first.');
        }

        try {
            // Format commits for the AI
            const commitMessages = commits.map(commit => {
                return `Commit: ${commit.hash.substring(0, 7)} | Date: ${new Date(commit.date).toISOString().split('T')[0]} | Author: ${commit.author} | Message: ${commit.message}`;
            }).join('\n');

            // Create the prompt for the AI
            const prompt = `
            I have the following git commits from a project. Please analyze them and provide a summary of the changes.
            Group related commits into features or fixes, and categorize them appropriately.
            Format the summary in markdown with sections for different types of changes (features, fixes, refactoring, etc.).
            
            Here are the commits:
            
            ${commitMessages}
            `;

            // Ensure the baseUrl doesn't end with a trailing slash
            const baseUrl = this.config!.baseUrl.endsWith('/') 
                ? this.config!.baseUrl.slice(0, -1) 
                : this.config!.baseUrl;

            // Construct the endpoint URL
            // The endpoint should be /chat/completions, not /v1/chat/completions since baseUrl already includes /v1
            const endpointUrl = `${baseUrl}/chat/completions`;
            
            console.log(`Making request to ${endpointUrl}`);
            console.log(`Using model: ${this.config!.model}`);
            
            // Get the system prompt (use default if not set)
            const systemPrompt = this.config!.systemPrompt || this.defaultSystemPrompt;
            
            // Make the API request
            const response = await axios.post(
                endpointUrl,
                {
                    model: this.config!.model,
                    messages: [
                        {
                            role: "system",
                            content: systemPrompt
                        },
                        {
                            role: "user",
                            content: prompt
                        }
                    ],
                    temperature: 0.7,
                    max_tokens: 2000,
                    stream: false // Ensure we're not using streaming for this request
                },
                {
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': `Bearer ${this.config!.apiKey}`
                    },
                    timeout: 60000 // 60 seconds timeout
                }
            );

            console.log('API response status:', response.status);
            
            // Extract the AI's response
            if (response.data && response.data.choices && response.data.choices.length > 0) {
                // The response format might be different depending on the API implementation
                // Try both formats that are commonly used
                if (response.data.choices[0].message && response.data.choices[0].message.content) {
                    return response.data.choices[0].message.content;
                } else if (response.data.choices[0].text) {
                    return response.data.choices[0].text;
                } else {
                    console.error('Unexpected response format:', JSON.stringify(response.data));
                    throw new Error('Unexpected API response format. The content field was not found in the response.');
                }
            } else {
                console.error('Invalid API response format:', JSON.stringify(response.data));
                throw new Error('Invalid API response format. Check the console for details.');
            }
        } catch (error) {
            if (axios.isAxiosError(error)) {
                if (error.response) {
                    // The request was made and the server responded with a status code
                    // that falls out of the range of 2xx
                    console.error('API error response:', error.response.status, error.response.data);
                    throw new Error(`API error: ${error.response.status} - ${JSON.stringify(error.response.data)}`);
                } else if (error.request) {
                    // The request was made but no response was received
                    console.error('No response received:', error.request);
                    throw new Error(`No response from API server. Check your network connection and baseUrl (${this.config!.baseUrl}).`);
                } else {
                    // Something happened in setting up the request that triggered an Error
                    console.error('Request setup error:', error.message);
                    throw new Error(`Request setup error: ${error.message}`);
                }
            } else {
                console.error('Unexpected error:', error);
                throw error;
            }
        }
    }
}
